package com.okq.util.security;

import com.okq.entity.Menu;
import com.okq.service.IMenuService;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

import java.util.*;

/**
 * 描述 : Spring Security加载菜单
 * 作者 : zdl
 * 日期 : 2017/3/15 13:26
 */
public class SecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
	/**
	 * 菜单接口
	 */
	@Autowired
	private IMenuService menuServiceImpl;

	private static Map<String, Collection<ConfigAttribute>> menuMap = null;

	/**
	 * 日志
	 */
	private static final Logger logger = Logger.getLogger(SecurityMetadataSource.class);

	/**
	 * 加载方法，从数据库中读取资源
	 */
	public void loadResourceDefine() {
		menuMap = new HashMap<>();
		List<Menu> menuList = menuServiceImpl.listAllMenu();
		for (Menu menu : menuList) {
			String menuUrl = menu.getUrl();
			String menuFlag = menu.getMenuCode();
			if (StringUtils.isNotBlank(menuUrl) && StringUtils.isNotBlank(menuFlag)) {
				// 处理url
				if (!menuUrl.startsWith("/")) {
					menuUrl = "/" + menuUrl;
				}
				Collection<ConfigAttribute> list = new ArrayList<>();
				list.add(new SecurityConfig(menuFlag));
				menuMap.put(menuUrl, list);
			}
		}
	}

	@Override
	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
		String url = ((FilterInvocation) object).getRequestUrl();
		if (logger.isDebugEnabled()) {
			logger.debug("正在访问的url是：" + url);
		}
		if (menuMap == null || (menuMap.size() == 0)) {
			return null;
		}
		Collection<ConfigAttribute> moduleCollection = menuMap.get(url);
		// 假如url在module表中不存在，否则判断权限
		if (moduleCollection == null) {
			return null;
		} else {
			return moduleCollection;
		}
	}

	/**
	 * 获取所有权限配置属性
	 */
	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		Set<ConfigAttribute> allAttribute = new HashSet<>();
		if (menuMap != null) {
			for (Map.Entry<String, Collection<ConfigAttribute>> entry : menuMap.entrySet()) {
				allAttribute.addAll(entry.getValue());
			}
		}
		return allAttribute;
	}

	@Override
	public boolean supports(Class<?> aClass) {
		return true;
	}

}
